package com.mgface.zookeeper.premitive;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import org.apache.log4j.Logger;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.KeeperException.NodeExistsException;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;

public class 排他锁 {
	private static Logger log = Logger.getLogger(排他锁.class);
	private static ZooKeeper client;
	private static String path = "/exclusive_lock";
	private final static String lock = path + "/L1";

	public static void cycleCreate(String lock) {
		try {
			client.create(lock, "排他锁stub".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);
			System.out.println("线程创建排它锁成功");
			System.out.println("10s之后处理完业务之后退出...");
			TimeUnit.SECONDS.sleep(10);
			client.delete(lock, -1);
		} catch (KeeperException | InterruptedException e1) {
			try {
				System.out.println("节点存在,值为:" + new String(client.getData(lock, false, null)) + ",进入监控状态...");
				client.exists(lock, true);// 监控lock节点
			} catch (KeeperException | InterruptedException e) {
				e.printStackTrace();
			}
		}
	}

	public static void main(String[] args) throws Exception {
		CountDownLatch on = new CountDownLatch(1);
		client = new ZooKeeper("localhost:2181,localhost:2182,localhost:2183", 10_000, e -> {
			try {
				if (e.getState() == KeeperState.SyncConnected) {
					switch (e.getType()) {
					case None:
						if (e.getPath() == null) {
							on.countDown();
						}
						break;
					case NodeDeleted:
						System.out.println(e.getPath() + "节点被移除.进入竞争锁创建状态...");
						cycleCreate(lock);
						break;
					default:
						break;
					}
				}
			} catch (Exception error) {
				error.getMessage();
			}

		});
		log.fatal("ZK状态:" + client.getState().toString());
		on.await();
		log.fatal("zookeeper session 建立完成");
		Stat stat = client.exists(path, false);
		if (stat == null) {
			try {
				client.create(path, "排他锁root".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
			} catch (Exception e1) {
				if (e1 instanceof NodeExistsException) {
					System.out.println(path + "根节点存在,值:" + new String(client.getData(path, false, null)));
				}
				e1.printStackTrace();
			}
		}
		TimeUnit.SECONDS.sleep(5);
		cycleCreate(lock);
		TimeUnit.SECONDS.sleep(150);
	}

}
